<template>
  <div class="fireworks-background">
    <canvas ref="canvasRef"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'

const props = defineProps({
  config: {
    type: Object,
    default: () => ({
      frequency: 'medium',
      colors: 'rainbow'
    })
  }
})

const canvasRef = ref(null)
let ctx = null
let fireworks = []
let particles = []
let animationId = null

class Firework {
  constructor(canvas) {
    this.canvas = canvas
    this.x = Math.random() * canvas.width
    this.y = canvas.height
    this.targetY = Math.random() * canvas.height * 0.5
    this.speed = Math.random() * 5 + 5
    this.color = this.getColor()
    this.trail = []
  }

  getColor() {
    if (props.config.colors === 'rainbow' || Array.isArray(props.config.colors)) {
      const colors = Array.isArray(props.config.colors) 
        ? props.config.colors
        : ['#ff0000', '#ff7f00', '#ffff00', '#00ff00', '#0000ff', '#4b0082', '#9400d3']
      return colors[Math.floor(Math.random() * colors.length)]
    }
    return props.config.colors
  }

  update() {
    this.trail.push({ x: this.x, y: this.y })
    if (this.trail.length > 10) {
      this.trail.shift()
    }

    this.y -= this.speed

    return this.y <= this.targetY
  }

  draw(context) {
    // 绘制拖尾
    this.trail.forEach((point, index) => {
      const opacity = index / this.trail.length
      context.save()
      context.globalAlpha = opacity * 0.5
      context.fillStyle = this.color
      context.beginPath()
      context.arc(point.x, point.y, 2, 0, Math.PI * 2)
      context.fill()
      context.restore()
    })

    // 绘制烟花本体
    context.save()
    context.fillStyle = this.color
    context.beginPath()
    context.arc(this.x, this.y, 3, 0, Math.PI * 2)
    context.fill()
    context.restore()
  }
}

class Particle {
  constructor(x, y, color) {
    this.x = x
    this.y = y
    this.color = color
    const angle = Math.random() * Math.PI * 2
    const speed = Math.random() * 5 + 2
    this.vx = Math.cos(angle) * speed
    this.vy = Math.sin(angle) * speed
    this.alpha = 1
    this.decay = Math.random() * 0.02 + 0.01
    this.size = Math.random() * 3 + 1
  }

  update() {
    this.x += this.vx
    this.y += this.vy
    this.vy += 0.1 // 重力
    this.alpha -= this.decay
  }

  draw(context) {
    if (this.alpha <= 0) return

    context.save()
    context.globalAlpha = this.alpha

    // 粒子光晕
    const gradient = context.createRadialGradient(
      this.x, this.y, 0,
      this.x, this.y, this.size * 2
    )
    gradient.addColorStop(0, this.color)
    gradient.addColorStop(0.5, this.color + '88')
    gradient.addColorStop(1, this.color + '00')

    context.fillStyle = gradient
    context.beginPath()
    context.arc(this.x, this.y, this.size * 2, 0, Math.PI * 2)
    context.fill()

    context.restore()
  }

  isAlive() {
    return this.alpha > 0
  }
}

const createFirework = () => {
  if (!canvasRef.value) return

  const frequencyMap = {
    low: 0.01,
    medium: 0.02,
    high: 0.04
  }
  const probability = frequencyMap[props.config.frequency] || 0.02

  if (Math.random() < probability) {
    fireworks.push(new Firework(canvasRef.value))
  }
}

const explode = (firework) => {
  const particleCount = 100
  for (let i = 0; i < particleCount; i++) {
    particles.push(new Particle(firework.x, firework.y, firework.color))
  }
}

const init = () => {
  const canvas = canvasRef.value
  if (!canvas) return

  canvas.width = canvas.offsetWidth
  canvas.height = canvas.offsetHeight
  ctx = canvas.getContext('2d')

  fireworks = []
  particles = []
}

const animate = () => {
  if (!ctx || !canvasRef.value) return

  // 半透明黑色覆盖，产生拖尾效果
  ctx.fillStyle = 'rgba(0, 0, 20, 0.1)'
  ctx.fillRect(0, 0, canvasRef.value.width, canvasRef.value.height)

  // 创建新烟花
  createFirework()

  // 更新烟花
  fireworks = fireworks.filter(firework => {
    const exploded = firework.update()
    firework.draw(ctx)
    
    if (exploded) {
      explode(firework)
      return false
    }
    return true
  })

  // 更新粒子
  particles = particles.filter(particle => {
    particle.update()
    particle.draw(ctx)
    return particle.isAlive()
  })

  animationId = requestAnimationFrame(animate)
}

const handleResize = () => {
  init()
}

onMounted(() => {
  init()
  animate()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', handleResize)
})

watch(() => props.config, () => {
  init()
}, { deep: true })
</script>

<style scoped>
.fireworks-background {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background: linear-gradient(180deg, #000428 0%, #004e92 100%);
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

